package org.shiki.hrm.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.shiki.hrm.constant.CourseTypeConstant;
import org.shiki.hrm.domain.CourseType;
import org.shiki.hrm.mapper.CourseTypeMapper;
import org.shiki.hrm.service.ICourseTypeService;
import org.shiki.hrm.util.AjaxResult;
import org.shiki.hrm.vo.CrumbsOv;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author shiki
 * @since 2022-03-12
 */
@Service
public class CourseTypeServiceImpl_redis extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {

	@Autowired
	private CourseTypeMapper courseTypeMapper;

	@Autowired
	private RedisTemplate redisTemplate;

	/**
	 * 缓存到redis
	 *
	 * @return
	 */
	@Override
	public AjaxResult treeData() {
		//List<CourseType> list = courseTypeMapper.treeData();
		List<CourseType> list;
		Object obj = redisTemplate.opsForValue().get(CourseTypeConstant.COURSE_TYPE_TREE_DATA);
		if (obj != null) {
			list = (List<CourseType>) obj;
		} else {
			list = loadTreeData();
			redisTemplate.opsForValue().set(CourseTypeConstant.COURSE_TYPE_TREE_DATA, list);
		}
		return AjaxResult.me().setResultObj(list);
	}

	@Override
	public AjaxResult getCrumbs(Long typeId) {
		List<CrumbsOv> ovs = new ArrayList<>();
		// 查询自己
		CourseType courseType = courseTypeMapper.selectById(typeId);
		String path = courseType.getPath();
		// 分割path
		String[] ids = path.split("\\.");
		for(String id : ids){
			CourseType own = courseTypeMapper.selectById(id);
			// 再查询兄弟
			Wrapper<CourseType> wrapper = new EntityWrapper<>();
			wrapper.eq("pid", own.getPid()).and().ne("id", own.getId());
			List<CourseType> bros = courseTypeMapper.selectList(wrapper);
			CrumbsOv ov = new CrumbsOv();
			ov.setBros(bros);
			ov.setOwn(own);
			ovs.add(ov);
		}
		return AjaxResult.me().setResultObj(ovs);
	}

	/**
	 * 查询全部数据并组装多层级
	 *
	 * @return
	 */
	private List<CourseType> loadTreeData() {
		List<CourseType> list = new ArrayList<>();
		// 查询全部的type
		List<CourseType> types = courseTypeMapper.selectList(null);
		// 组装一对一关系
		Map<Long, CourseType> map = new HashMap<>();
		types.stream().forEach(type -> {
			map.put(type.getId(), type);
		});
		// 组装层级关系
		types.stream().forEach(type -> {
			if (type.getPid() == 0) {
				list.add(type);
			} else {
				// 获取父级id
				Long pid = type.getPid();
				// 获取父级type
				CourseType courseType = map.get(pid);
				// 存入父级children属性
				courseType.getChildren().add(type);
			}
		});
		return list;
	}

	@Override
	public boolean deleteById(Serializable id) {
		redisTemplate.delete(CourseTypeConstant.COURSE_TYPE_TREE_DATA);
		boolean b = super.deleteById(id);
		try {
			Thread.sleep(50L);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		redisTemplate.delete(CourseTypeConstant.COURSE_TYPE_TREE_DATA);
		return b;
	}

	@Override
	public boolean delete(Wrapper<CourseType> wrapper) {
		redisTemplate.delete(CourseTypeConstant.COURSE_TYPE_TREE_DATA);
		boolean b = super.delete(wrapper);
		try {
			Thread.sleep(50L);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		redisTemplate.delete(CourseTypeConstant.COURSE_TYPE_TREE_DATA);
		return b;
	}

	@Override
	public boolean insert(CourseType entity) {
		redisTemplate.delete(CourseTypeConstant.COURSE_TYPE_TREE_DATA);
		boolean b = super.insert(entity);
		try {
			Thread.sleep(50L);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		redisTemplate.delete(CourseTypeConstant.COURSE_TYPE_TREE_DATA);
		return b;
	}

	@Override
	public boolean updateById(CourseType entity) {
		redisTemplate.delete(CourseTypeConstant.COURSE_TYPE_TREE_DATA);
		boolean b = super.updateById(entity);
		try {
			Thread.sleep(50L);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		redisTemplate.delete(CourseTypeConstant.COURSE_TYPE_TREE_DATA);
		return b;
	}


}
